package gtpengine

import (
	"fmt"
	"strings"
	"time"
)

type GTPClient struct {
	conn        *GTPConnection
	pro_version string
	Result      string
	info        *strings.Builder
	Sleep       int
}

// 创建GTP命令
func NewGtpClient(conn *GTPConnection) *GTPClient {
	util := GTPClient{
		info: new(strings.Builder),
	}
	util.conn = conn
	go conn.ListenInfo(func(i string) {
		util.info.WriteString(i)
	})
	ver, err := util.SendCMD("protocol_version")
	if err == nil {
		util.pro_version = ver
	} else {
		util.pro_version = "2"
	}
	return &util
}
func (g *GTPClient) ShowLog(flag bool) {
	g.conn.ShowLog = flag
}

// 判断命令是否支持
func (g *GTPClient) KnowCommand(cmd string) bool {
	value, err := g.SendCMD("known_command " + cmd)
	if err != nil {
		return false
	}
	if strings.ToLower(strings.TrimSpace(value)) != "true" {
		return false
	}
	return true
}

// 设置贴目
func (g *GTPClient) Komi(komi float64) (string, error) {
	return g.SendCMD(fmt.Sprintf("komi %v", komi))
}

// 设置棋盘大小
func (g *GTPClient) BoardSize(size int) (string, error) {
	return g.SendCMD(fmt.Sprintf("boardsize %v", size))
}

// 获取AI落子
func (g *GTPClient) GenMove(color string) (string, error) {
	color = strings.ToUpper(color)
	command := "genmove " + color
	return g.SendCMD(command)
}

// 人落子
func (g *GTPClient) Move(color, coor string) (string, error) {
	color = strings.ToUpper(color)
	return g.SendCMD(fmt.Sprintf("play %s %s", color, coor))
}

// 加载SGF文件
func (g *GTPClient) LoadSgf(file string) (string, error) {
	command := fmt.Sprintf("loadsgf %s", file)
	return g.SendCMD(command)
}

// 获取当前盘面形势判断
func (g *GTPClient) FinalStatusList(cmd string) (string, error) {
	command := fmt.Sprintf("final_status_list %s", cmd)
	return g.SendCMD(command)
}

// 设置AI级别
func (g *GTPClient) SetLevel(seed int) (string, error) {
	command := fmt.Sprintf("level %d", seed)
	return g.SendCMD(command)
}

// 设置AI随机数
func (g *GTPClient) SetRandomSeed(seed int) (string, error) {
	command := fmt.Sprintf("set_random_seed %d", seed)
	return g.SendCMD(command)
}

// 显示棋盘
func (g *GTPClient) ShowBoard() (string, error) {
	return g.SendCMD("showboard")
}

// 清空棋盘
func (g *GTPClient) ClearBoard() (string, error) {
	return g.SendCMD("clear_board")
}

//打印SGF
func (g *GTPClient) PrintSgf() (string, error) {
	return g.SendCMD("printsgf")
}

// 设置时间规则
func (g *GTPClient) TimeSetting(baseTime, byoTime, byoStones int) (string, error) {
	return g.SendCMD(fmt.Sprintf("time_settings %d %d %d", baseTime, byoTime, byoStones))
}

// 设置KGS time
func (g *GTPClient) KGSTimeSetting(mainTime, readTime, readLimit int) (string, error) {
	return g.SendCMD(fmt.Sprintf("kgs-time_settings byoyomi %d %d %d", mainTime, readTime, readLimit))
}

//获取结果
func (g *GTPClient) FinalScore() (string, error) {
	return g.SendCMD("final_score")
}

//悔棋
func (g *GTPClient) Undo() (string, error) {
	return g.SendCMD("undo")
}

//设置时间
func (g *GTPClient) TimeLeft(color string, mainTime, stones int) (string, error) {
	return g.SendCMD(fmt.Sprintf("time_left %s %d %d", color, mainTime, stones))
}

//退出
func (g *GTPClient) Quit() (string, error) {
	r, err := g.SendCMD("Quit")
	g.conn.Close()
	return r, err
}

// 方式自定义命令
func (g *GTPClient) SendCMD(cmd string) (string, error) {
	defer func() {
		time.Sleep(time.Duration(g.Sleep) * time.Millisecond)
		g.Result = g.info.String()
	}()
	g.info.Reset()
	result, err := g.conn.Exec(cmd)
	return result, err
}
